<?php

namespace App\Service;

use App\Model\SmsLog;
use App\Model\SmsTemplate;
use Exception;
use Hyperf\Context\Context;
use TencentCloud\Common\Credential;
use TencentCloud\Sms\V20210111\Models\SendSmsRequest;
use TencentCloud\Sms\V20210111\SmsClient;
use function Hyperf\Support\env;

class SmsService
{
    /**
     * 发送
     * @throws Exception
     */
    public static function send($mobile, $scene, $data): true
    {
        $template = SmsTemplate::query()->where('scene', $scene)->first();
        if (!$template) {
            throw new Exception('场景消息模板不存在');
        }
        $template['params'] = new_json_decode($template['params']);
        preg_match_all('/\{(\w+)}/', $template['content'], $matches);
        $paramSet = [];
        if (!empty($matches[1])) {
            foreach ($matches[1] as $k) {
                $paramSet[$k] = $data[$k] ?? '';
            }
        }

        $cred = new Credential(env('SMS_SECRET_ID'), env('SMS_SECRET_KEY'));

        // 实例化要请求产品的client对象,clientProfile是可选的
        $client = new SmsClient($cred, env('SMS_REGION'));

        // 实例化一个请求对象,每个接口都会对应一个request对象
        $req = new SendSmsRequest();
        $req->fromJsonString(json_encode([
            'PhoneNumberSet' => is_array($mobile) ? $mobile : [$mobile],
            'SmsSdkAppId' => env('SMS_APPID'),
            'SignName' => env('SMS_SIGN_NAME'),
            'TemplateId' => $template['template_id'],
            'TemplateParamSet' => $paramSet,
        ]));

        $resp = $client->SendSms($req);
        if ($resp->SendStatusSet[0]->Code == 'Ok') {
            SmsLog::create([
                'vendor_id' => $template['vendor_id'],
                'scene' => $template['scene'],
                'typeid' => 0,
                'userid' => Context::get('userid', 0),
                'nickname' => Context::get('nickname', ''),
                'mobile' => is_array($mobile) ? implode(',', $mobile) : $mobile,
                'content' => str_replace(array_keys($paramSet), array_values($paramSet), $template['content']),
                'validate_code' => $paramSet['code'] ?? '',
                'validate_time' => 0,
                'add_time' => time(),
            ]);
            return true;
        } else {
            throw new Exception('发送失败:' . $resp->SendStatusSet[0]->Code);
        }
    }
}